#include "LineSegment.h"
#include <iostream>

LineSegment::LineSegment(float fromX, float fromY, float toX, float toY)
{
	m_from.x = fromX;
	m_from.y = fromY;
	m_to.x = toX;
	m_to.y = toY;

	//Vector2D
	m_normal = GetVectorByAngleDeg(GetPolarAngleDeg( &( Substract(&m_from, &m_to) ) ) - 90);
}

LineSegment::LineSegment(const Vector2D *from, const Vector2D *to)
{
	m_from = *from;
	m_to = *to;
	m_normal = GetVectorByAngleDeg(GetPolarAngleDeg( &( Substract(&m_from, &m_to) ) ) - 90);
}

Vector2D LineSegment::GetFromPoint() const
{
	return m_from;
}

Vector2D LineSegment::GetToPoint() const
{
	return m_to;
}

Vector2D LineSegment::GetNormal() const
{
	return m_normal;
}

// BONUS
bool LineSegment::IntersectsWith(const LineSegment *seg)
{
	// si ces variables deviennent 0, la droite est verticale
	float vertical1;
	float vertical2;

	float a1 = (m_from.y - m_to.y) / ( (vertical1 = (m_from.x - m_to.x)) != 0 ? vertical1 : 1);
	float b1 = m_from.y - (a1 * m_from.x);
	
	float a2 = (seg->GetFromPoint().y - seg->GetToPoint().y) / ((vertical2 = ( seg->GetFromPoint().x - seg->GetToPoint().x)) != 0 ? vertical2 : 1);
	float b2 = seg->GetFromPoint().y - (a2 * seg->GetFromPoint().x);
	
	if(vertical1 == 0)
	{
		if(vertical2 == 0)
		{
			float smallestY2;
			float biggestY2;

			if(seg->GetFromPoint().y < seg->GetToPoint().y)
			{
				smallestY2 = seg->GetFromPoint().y, biggestY2 = seg->GetToPoint().y;
			}
			else 
			{
				biggestY2 = seg->GetFromPoint().y, smallestY2 = seg->GetToPoint().y;
			}
			return !(	(m_from.y < smallestY2 && m_to.y < smallestY2)
						||
						(m_from.y > biggestY2 && m_to.y > biggestY2));
		}
		else // only 1st is vertical
		{
			float Y1 = a2 * m_from.x + b2;
			return ((seg->GetFromPoint().x <= m_from.x && seg->GetToPoint().x >= m_from.x)
					||
					(seg->GetToPoint().x <= m_from.x && seg->GetFromPoint().x >= m_from.x))
					&&
					!(	(m_from.y < Y1 && m_to.y < Y1)
						||
						(m_from.y > Y1 && m_to.y > Y1));
		}
	}
	
	if(vertical2 == 0) // only 2nd is vertical
	{
		float Y2 = a1 * seg->GetFromPoint().x + b1;
		return ((m_from.x <= seg->GetFromPoint().x && m_to.x >= seg->GetFromPoint().x)
				||
				(m_to.x <= seg->GetFromPoint().x && m_from.x >= seg->GetFromPoint().x))
				&&
				!(	(seg->GetFromPoint().y < Y2 && seg->GetToPoint().y < Y2)
					||
					(seg->GetFromPoint().y > Y2 && seg->GetToPoint().y > Y2));
	}
	
	float smallestX2;
	float biggestX2;

	if (seg->GetFromPoint().x < seg->GetToPoint().x)
	{
		smallestX2 = seg->GetFromPoint().x;
		biggestX2 = seg->GetToPoint().x;
	}
	else 
	{
		smallestX2 = seg->GetToPoint().x;
		biggestX2 = seg->GetFromPoint().x;
	}

	// cas parallele
	if(a1 == a2)
	{
		// cas confondue
		if(b1 == b2)
		{
			return !(	(m_from.x < smallestX2 && m_to.x < smallestX2)
						||
						(m_from.x > biggestX2 && m_to.x > biggestX2));
		}
		else // cas distinctes
		{
			return false;
		}
	}
	else if (b1 == b2) // cas intersection x == 0
	{
		return (( (m_from.x <= 0 && m_to.x >= 0) || (m_from.x >= 0 && m_to.x <= 0) )
				&&
				( (smallestX2 <= 0 && biggestX2 >= 0)));
	}
	else // cas intersection normale
	{
		float xIntersect = (b2 - b1)/ (a1 - a2);
		// dans le fond, ca sert a rien de calculer aussi l'intersection en y
		//float yIntersect = a1 * xIntersect + b1;
		return (( (m_from.x <= xIntersect && m_to.x >= xIntersect) || (m_from.x >= xIntersect && m_to.x <= xIntersect) )
				&&
				( (smallestX2 <= xIntersect && biggestX2 >= xIntersect)));
	}
}